package com.qys.livesMall.anchor.business;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.google.common.collect.Lists;
import com.qys.livesMall.anchor.constants.RedisConstant;
import com.qys.livesMall.anchor.event.GiveLikeEvent;
import com.qys.livesMall.anchor.event.pojo.GiveLikeEventPOJO;
import com.qys.livesMall.anchor.mapper.AnchorRewardConfigMapper;
import com.qys.livesMall.anchor.model.dto.lives.app.AnchorLivesDTO;
import com.qys.livesMall.anchor.model.dto.lives.app.LikeLivesRoomDTO;
import com.qys.livesMall.anchor.model.entity.AnchorLivesRoom;
import com.qys.livesMall.anchor.model.entity.AnchorLivesSession;
import com.qys.livesMall.anchor.model.entity.AnchorRewardConfig;
import com.qys.livesMall.anchor.model.pojo.GiveLikeCachePOJO;
import com.qys.livesMall.anchor.model.vo.lives.app.AnchorLivesRoomVO;
import com.qys.livesMall.anchor.model.vo.lives.app.AnchorLivesVO;
import com.qys.livesMall.anchor.model.vo.lives.app.LikeListVO;
import com.qys.livesMall.anchor.service.AnchorLivesRoomService;
import com.qys.livesMall.anchor.service.AnchorLivesSessionService;
import com.qys.livesMall.cache.RedisCache;
import com.qys.livesMall.common.exception.QysException;
import com.qys.livesMall.common.utils.MessageUtils;
import com.qys.livesMall.finance.enums.AccountBusinessTypeEnum;
import com.qys.livesMall.finance.model.dto.FinancePayDTO;
import com.qys.livesMall.finance.service.FinanceBusinessService;
import com.qys.livesMall.finance.util.BusinessNoUtil;
import jakarta.annotation.Resource;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

import static com.qys.livesMall.anchor.constants.RedisConstant.LIVE_ROOM_ONE_HOURS_LIKE_LIST;

@Service
@Slf4j
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
public class LiveRoomBusiness {

    private final RedisCache redisCache;
    private final ApplicationContext applicationContext;
    private final AnchorLivesRoomService anchorLivesRoomService;
    private final AnchorLivesSessionService anchorLivesSessionService;
    private final AnchorRewardConfigMapper anchorRewardConfigMapper;
    private final FinanceBusinessService financeBusinessService;

    /**
     * 根据直播间编号查询直播间详情
     */
    public AnchorLivesRoomVO getLiveRoomBy(String livesRoomNum) {
        //获取主播直播间数据
        AnchorLivesRoom anchorLivesRoom = anchorLivesRoomService.checkIsLive(livesRoomNum);
        //获取当前主播正在开播场次
        AnchorLivesSession anchorLivesSession=anchorLivesSessionService.getIsStarted(anchorLivesRoom.getId());

        AnchorLivesRoomVO vo=new AnchorLivesRoomVO();
        vo.setAnchorId(anchorLivesRoom.getAnchorId());
        vo.setAnchorName(anchorLivesRoom.getAnchorName());
        vo.setLivesRoomNum(anchorLivesRoom.getLivesRoomNum());
        vo.setLivesSessionId(anchorLivesSession.getId());
//        vo.setAudienceNum();//观众数量
//        vo.setFocusOnFlag();//是否关注该主播
        return vo;
    }

    /**
     * 直播间点赞
     */
    public void giveLikeLivesRoom(LikeLivesRoomDTO likeLivesRoomDTO) {
        //获取直播间数据
        anchorLivesRoomService.checkIsLive(likeLivesRoomDTO.getLivesRoomNum());
        AnchorLivesSession session = anchorLivesSessionService.getById(likeLivesRoomDTO.getLivesSessionId());
        if (session == null) {
            throw new QysException(MessageUtils.message("直播间场次不存在"));
        }
        applicationContext.publishEvent(new GiveLikeEvent(GiveLikeEventPOJO.builder()
                .livesRoomNum(likeLivesRoomDTO.getLivesRoomNum())
                .livesSessionId(likeLivesRoomDTO.getLivesSessionId())
                .likeNum(likeLivesRoomDTO.getLikeNum())
                .build()));
    }


    public List<LikeListVO> heatLivesRoom() {
        List<GiveLikeCachePOJO> list = redisCache.getCacheList(getLiveListKey());
        list = list.stream().sorted(Comparator.comparing(GiveLikeCachePOJO::getOneHoursLikeNum).reversed()).limit(20).collect(Collectors.toList());
        return BeanUtil.copyToList(list, LikeListVO.class);
    }


    private String getLiveListKey() {
        return LIVE_ROOM_ONE_HOURS_LIKE_LIST;
    }


    public IPage<AnchorLivesVO> getAnchorLivesRoom(AnchorLivesDTO anchorLivesDTO) {
       return anchorLivesRoomService.getAnchorLivesRoom(anchorLivesDTO);
    }

    public void recordViewing(Long livesSessionId, Long userId) {
        //排除主播记录自己
        AnchorLivesRoom room = anchorLivesRoomService.getRoomByUserId(userId);
        if(room != null){
            AnchorLivesSession livesSession = anchorLivesSessionService.getIsStarted(room.getId());
            if(livesSession != null && Objects.equals(livesSessionId, livesSession.getId())){
                return;
            }
        }
        //记录用户观看行为
        anchorLivesRoomService.recordViewing(userId);

        //判断用户观看时长是否达标
        int total = anchorLivesRoomService.getUserViewTime(userId);

        //查询奖励配置
        AnchorRewardConfig config = anchorRewardConfigMapper.selectOne(Wrappers.<AnchorRewardConfig>lambdaQuery()
                .eq(AnchorRewardConfig::getAwardType, 7)
                .le(AnchorRewardConfig::getAwardCondition, total/60)
                .orderByDesc(AnchorRewardConfig::getAwardCondition)
                .last("limit 1")
        );

        if(config != null){
            //判断是否领取过该阶段奖励
            int rewarded = anchorRewardConfigMapper.rewardJudgment(config.getConId(), userId, false);
            if(rewarded > 0){
                return;
            }
            FinancePayDTO payDTO = new FinancePayDTO();
            payDTO.setUserId(userId);
            payDTO.setBusinessType(AccountBusinessTypeEnum.WATCH_LIVE_TIME_BONUS);
            payDTO.setAmountIncurred(config.getAwardAmount());
            payDTO.setBusinessNo(BusinessNoUtil.get(AccountBusinessTypeEnum.WATCH_LIVE_TIME_BONUS));
            payDTO.setDescription("用户观看直播时长奖励");
            financeBusinessService.pay(payDTO);
            if (payDTO.getSuccess()) {
                anchorRewardConfigMapper.keepRecords(config.getConId(), userId);
                log.info("用户观看直播时长奖励成功, 奖励配置id:{}，userId:{}", config.getConId(), userId);
            } else {
                log.info("用户观看直播时长奖励失败, 奖励配置id:{}，userId:{}，原因：{}", config.getConId(), userId, payDTO.getMessage());
            }
        }
    }


    public List<String> getNavyNum(Long livesSessionId) {
        String key = RedisConstant.LIVE_ONLINE_NUMBER_PREFIX + livesSessionId;
        Set<String> cacheSet = redisCache.getCacheSet(key);
        if(CollectionUtil.isEmpty(cacheSet)){
            return null;
        }
        List<String> list = Lists.newArrayList();
        for (String item : cacheSet) {
            if(item.startsWith("navy")){
                String substring = item.substring(4);
                list.add(substring);
            }
        }
        return list;
    }
}
